/**
 * Created by jiachenpan on 16/11/18.
 */
import moment from 'moment'
import fileSaver from 'file-saver'

import store from '../store'
import router from '../router'

export function parseTime(time, cFormat) {
  if (arguments.length === 0) {
    return null
  }
  const format = cFormat || '{y}-{m}-{d} {h}:{i}:{s}'
  let date
  if (typeof time === 'object') {
    date = time
  } else {
    if (('' + time).length === 10) time = parseInt(time) * 1000
    date = new Date(time)
  }
  const formatObj = {
    y: date.getFullYear(),
    m: date.getMonth() + 1,
    d: date.getDate(),
    h: date.getHours(),
    i: date.getMinutes(),
    s: date.getSeconds(),
    a: date.getDay()
  }
  const time_str = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => {
    let value = formatObj[key]
    if (key === 'a') return ['一', '二', '三', '四', '五', '六', '日'][value - 1]
    if (result.length > 0 && value < 10) {
      value = '0' + value
    }
    return value || 0
  })
  return time_str
}

export function formatTime(time, option) {
  time = +time * 1000
  const d = new Date(time)
  const now = Date.now()

  const diff = (now - d) / 1000

  if (diff < 30) {
    return '刚刚'
  } else if (diff < 3600) { // less 1 hour
    return Math.ceil(diff / 60) + '分钟前'
  } else if (diff < 3600 * 24) {
    return Math.ceil(diff / 3600) + '小时前'
  } else if (diff < 3600 * 24 * 2) {
    return '1天前'
  }
  if (option) {
    return parseTime(time, option)
  } else {
    return d.getMonth() + 1 + '月' + d.getDate() + '日' + d.getHours() + '时' + d.getMinutes() + '分'
  }
}

// 格式化时间
export function getQueryObject(url) {
  url = url == null ? window.location.href : url
  const search = url.substring(url.lastIndexOf('?') + 1)
  const obj = {}
  const reg = /([^?&=]+)=([^?&=]*)/g
  search.replace(reg, (rs, $1, $2) => {
    const name = decodeURIComponent($1)
    let val = decodeURIComponent($2)
    val = String(val)
    obj[name] = val
    return rs
  })
  return obj
}

/**
 *get getByteLen
 * @param {Sting} val input value
 * @returns {number} output value
 */
export function getByteLen(val) {
  let len = 0
  for (let i = 0; i < val.length; i++) {
    if (val[i].match(/[^\x20\xff]/ig) != null) {
      len += 1
    } else {
      len += 0.5
    }
  }
  return Math.floor(len)
}

export function cleanArray(actual) {
  const newArray = []
  for (let i = 0; i < actual.length; i++) {
    if (actual[i]) {
      newArray.push(actual[i])
    }
  }
  return newArray
}

export function param(json) {
  if (!json) return ''
  return cleanArray(Object.keys(json).map(key => {
    if (json[key] === undefined) return ''
    return encodeURIComponent(key) + '=' +
      encodeURIComponent(json[key])
  })).join('&')
}

export function param2Obj(url) {
  const search = url.split('?')[1]
  if (!search) {
    return {}
  }
  return JSON.parse('{"' + decodeURIComponent(search).replace(/"/g, '\\"').replace(/&/g, '","').replace(/=/g, '":"') + '"}')
}

export function html2Text(val) {
  const div = document.createElement('div')
  div.innerHTML = val
  return div.textContent || div.innerText
}

export function objectMerge(target, source) {
  /* Merges two  objects,
     giving the last one precedence */

  if (typeof target !== 'object') {
    target = {}
  }
  if (Array.isArray(source)) {
    return source.slice()
  }
  for (const property in source) {
    if (source.hasOwnProperty(property)) {
      const sourceProperty = source[property]
      if (typeof sourceProperty === 'object') {
        target[property] = objectMerge(target[property], sourceProperty)
        continue
      }
      target[property] = sourceProperty
    }
  }
  return target
}

export function scrollTo(element, to, duration) {
  if (duration <= 0) return
  const difference = to - element.scrollTop
  const perTick = difference / duration * 10
  setTimeout(() => {
    element.scrollTop = element.scrollTop + perTick
    if (element.scrollTop === to) return
    scrollTo(element, to, duration - 10)
  }, 10)
}

export function toggleClass(element, className) {
  if (!element || !className) {
    return
  }
  let classString = element.className
  const nameIndex = classString.indexOf(className)
  if (nameIndex === -1) {
    classString += '' + className
  } else {
    classString = classString.substr(0, nameIndex) + classString.substr(nameIndex + className.length)
  }
  element.className = classString
}

export const pickerOptions = [{
  text: '今天',
  onClick(picker) {
    const end = new Date()
    const start = new Date(new Date().toDateString())
    end.setTime(start.getTime())
    picker.$emit('pick', [start, end])
  }
}, {
  text: '最近一周',
  onClick(picker) {
    const end = new Date(new Date().toDateString())
    const start = new Date()
    start.setTime(end.getTime() - 3600 * 1000 * 24 * 7)
    picker.$emit('pick', [start, end])
  }
}, {
  text: '最近一个月',
  onClick(picker) {
    const end = new Date(new Date().toDateString())
    const start = new Date()
    start.setTime(start.getTime() - 3600 * 1000 * 24 * 30)
    picker.$emit('pick', [start, end])
  }
}, {
  text: '最近三个月',
  onClick(picker) {
    const end = new Date(new Date().toDateString())
    const start = new Date()
    start.setTime(start.getTime() - 3600 * 1000 * 24 * 90)
    picker.$emit('pick', [start, end])
  }
}]

export function getTime(type) {
  if (type === 'start') {
    return new Date().getTime() - 3600 * 1000 * 24 * 90
  } else {
    return new Date(new Date().toDateString())
  }
}

export function debounce(func, wait, immediate) {
  let timeout, args, context, timestamp, result

  const later = function () {
    // 据上一次触发时间间隔
    const last = +new Date() - timestamp

    // 上次被包装函数被调用时间间隔last小于设定时间间隔wait
    if (last < wait && last > 0) {
      timeout = setTimeout(later, wait - last)
    } else {
      timeout = null
      // 如果设定为immediate===true，因为开始边界已经调用过了此处无需调用
      if (!immediate) {
        result = func.apply(context, args)
        if (!timeout) context = args = null
      }
    }
  }

  return function (...args) {
    context = this
    timestamp = +new Date()
    const callNow = immediate && !timeout
    // 如果延时不存在，重新设定延时
    if (!timeout) timeout = setTimeout(later, wait)
    if (callNow) {
      result = func.apply(context, args)
      context = args = null
    }

    return result
  }
}

export function deepClone(source) {
  if (!source && typeof source !== 'object') {
    throw new Error('error arguments', 'shallowClone')
  }
  const targetObj = source.constructor === Array ? [] : {}
  Object.keys(source).forEach((keys) => {
    if (source[keys] && typeof source[keys] === 'object') {
      targetObj[keys] = source[keys].constructor === Array ? [] : {}
      targetObj[keys] = deepClone(source[keys])
    } else {
      targetObj[keys] = source[keys]
    }
  })
  return targetObj
}

/*
  格式化检索条件
*/
export function transformQueryCondition(query) {
  const searchCon = {
    'condition': undefined,
    'sort': query.sort,
    'fields': query.fields,
    'otherSearchBean': query.otherSearchBean,
    'rowBounds': query.rowBounds
  }
  // const searchCon = Object.assign({}, query)
  if (searchCon.rowBounds) {
    if (searchCon.rowBounds.offset <= 0) {
      searchCon.rowBounds.offset = 0
      // } else {
      // searchCon.rowBounds.offset = searchCon.rowBounds.offset - 1
    }
  }
  // searchCon.condition = undefined

  const condition = []
  for (const item in query.condition) {
    // BETWEEN情况
    if (query.condition[item].type === 'BETWEEN') {
      if (!query.condition[item].value) {
        continue
      }
    }
    // ISNULL情况
    if (query.condition[item].type === 'ISNULL') {
      const input = {
        'property': query.condition[item].property,
        'value': [],
        'type': query.condition[item].type
      }
      condition.push(input)
      continue
    }
    // 过滤不存在的字段
    if (query.condition[item].value !== undefined && query.condition[item].value !== '') {
      if (Array.isArray(query.condition[item].value)) {
        if (query.condition[item].value[0] !== '' && query.condition[item].value[1] !== '') {
          const input = {
            'property': query.condition[item].property,
            'value': query.condition[item].value,
            'type': query.condition[item].type
          }
          condition.push(input)
        }
      } else {
        const input = {
          'property': query.condition[item].property,
          'value': query.condition[item].value,
          'type': query.condition[item].type
        }
        condition.push(input)
      }
    }
  }
  searchCon.condition = condition

  return searchCon
}

/*
  格式化时间
*/
export function parseStrDate(dateStr, oldformat = 'YYYYMMDDHHmmss', newformat = 'YYYY-MM-DD HH:mm:ss') {
  if (arguments.length === 0) {
    return null
  }
  if (!dateStr) {
    return null
  }
  return moment(dateStr, oldformat).format(newformat)
}

// 去掉回车换行
export function replaceEnterChar(replaceStr) {
  if (replaceStr) {
    let resultStr = replaceStr.replace(/\r\n/g, '<br/>')
    resultStr = resultStr.replace(/\n/g, '<br/>')
    return resultStr
  } else {
    return replaceStr
  }
}

export function saveBlobFile(content, fileName) {
  fileSaver.saveAs(content, fileName)
}

// 将更新json中，null字段替换为空串。防止不更新
export function transItemNull2Blank(updatrecordeItem) {
  const record = updatrecordeItem.record
  for (const ele in record) {
    if (record[ele] == null) {
      record[ele] = ''
    }
  }
  return updatrecordeItem
}

/**
 * 【文本比较插件】
 * 传递两个参数dom1、dom2，以dom1为基准进行比较。
 * 0）dom1和dom2不能都为空；
 * 1）如果dom1不存在，则dom2为新增效果
 * 2）如果dom2不存在，则dom1为删除效果
 * 3）如果dom1和dom2存在，则进行文本差异比较
 *
 */

export function MyCompare(contentArray) {
  var stylesArray = ['#000;', '#f00;', '#0ff;', '#00f;', '#ff0;', '#f0f;', '#090;', '#f9f;', '#0f9;', '#9f0;']
  if (contentArray.length <= 1) {
    return {
      userColor: '',
      text: ''
    }
  }
  var tempBefore = []
  for (var i = 0; i < contentArray[0].content.length; i++) {
    tempBefore.push([{
      t: contentArray[0].content[i],
      o: 'add',
      u: contentArray[0].name
    }])
  }
  for (var turn = 1; turn < contentArray.length; turn++) {
    var tempNext = JSON.parse(JSON.stringify(tempBefore))
    var py = 0
    var j = 0
    for (var i = 0; i < tempBefore.length; i++) {
      if (tempBefore[i][tempBefore[i].length - 1].o == 'remove') { continue }
      j = 0
      for (; j < contentArray[turn].content.length; j++) {
        if (i >= tempBefore.length) { break }
        var ooo = tempBefore[i][tempBefore[i].length - 1].t
        var ppp = contentArray[turn].content[j]
        if (tempBefore[i][tempBefore[i].length - 1].t == contentArray[turn].content[j]) {
          i++
          continue
        } else {
          var k = j // 后面的
          var l = i // 前面的
          var findmin = {
            i: i,
            pos: 99999999
          }
          for (var ii = i; ii < tempBefore.length; ii++) {
            if (tempBefore[ii][tempBefore[ii].length - 1].o == 'remove') { continue }
            for (var kk = j; kk < contentArray[turn].content.length; kk++) {
              if (tempBefore[ii][tempBefore[ii].length - 1].t == contentArray[turn].content[kk]) {
                if (findmin.pos > kk) {
                  findmin.i = ii
                  findmin.pos = kk
                }
                break
              }
            }
          }
          if (findmin.pos == 99999999) {
            tempNext.splice(i + py, 0, [{
              t: contentArray[turn].content[k],
              o: 'add',
              u: contentArray[turn].name
            }])
            py += 1
          } else {
            var removeNumber = findmin.i - i
            var addNumber = findmin.pos - j
            for (var rj = 0; rj < removeNumber; rj++) {
              if (tempNext[i + py + rj][tempNext[i + py + rj].length - 1].o == 'remove') { continue }
              tempNext[i + py + rj].push({
                t: tempNext[i + py + rj][0].t,
                o: 'remove',
                u: contentArray[turn].name
              })
            }
            for (var aj = 0; aj < addNumber; aj++) {
              tempNext.splice(i + py + aj, 0, [{
                t: contentArray[turn].content[k + aj],
                o: 'add',
                u: contentArray[turn].name
              }])
            }
            py += addNumber
            i = findmin.i + 1
            j = findmin.pos
          }
        }
      }
      for (var rj = i; rj < tempBefore.length; rj++) {
        if (tempNext[rj + py][tempNext[py + rj].length - 1].o == 'remove') { continue }
        tempNext[py + rj].push({
          t: tempNext[py + rj][0].t,
          o: 'remove',
          u: contentArray[turn].name
        })
      }
      break
    }
    for (; j < contentArray[turn].content.length; j++) {
      tempNext.push([{
        t: contentArray[turn].content[j],
        o: 'add',
        u: contentArray[turn].name
      }])
    }
    tempBefore = tempNext
  }
  var styleLinkUser = {}
  var styleStr = ''
  var i = 0
  contentArray.forEach(function (c) {
    styleLinkUser[c.name] = stylesArray[i]
    styleStr += '<span style="color:' + stylesArray[i] + 'border: 1px solid ' + stylesArray[i] + ';padding: 3px 8px;margin: 0 10px 0 0;">' + c.name + '</span>'
    i++
    if (i >= 10) { i = 0 }
  })
  var resultText = ''
  tempBefore.forEach(function (t) {
    resultText += ('<span style="color:' + styleLinkUser[t[t.length - 1].u] + ' ' + (t[t.length - 1]
      .o == 'remove' ? 'text-decoration: line-through;' : '') + '">' + t[t.length - 1].t +
      '</span>')
  })
  return {
    userColor: styleStr,
    text: resultText
  }
  //   if (!dom1 && !dom2) {
  //     console.log('参数错误：dom1、dom2不能为空。')
  //     return
  //   } else if (!dom1) {
  //     // dom1为空：新增
  //     dom2.style.color = '#90EE90'
  //   } else if (!dom2) {
  //     // dom2为空：删除
  //     dom1.style.color = '#FF6347'
  //     dom1.style.textDecoration = 'line-through'
  //   } else {
  //     // 进行差异比较
  //     var result = _eq({
  //       value1: dom1.innerText || dom1.innerHTML,
  //       value2: dom2.innerText || dom2.innerHTML
  //     })
  //     dom1.innerHTML = result.value1
  //     dom2.innerHTML = result.value2
  //   }
  // }
  // export function _eq(op) {
  //   if (!op) {
  //     return op
  //   }
  //   if (!op.value1_style) {
  //     op.value1_style = 'background-color:#FEC8C8;'
  //   }
  //   if (!op.value2_style) {
  //     op.value2_style = 'background-color:#FEC8C8;'
  //   }
  //   if (!op.eq_min) {
  //     op.eq_min = 3
  //   }
  //   if (!op.eq_index) {
  //     op.eq_index = 5
  //   }
  //   if (!op.value1 || !op.value2) {
  //     return op
  //   }
  //   var ps = {
  //     v1_i: 0,
  //     v1_new_value: '',
  //     v2_i: 0,
  //     v2_new_value: ''
  //   }
  //   while (ps.v1_i < op.value1.length && ps.v2_i < op.value2.length) {
  //     if (op.value1[ps.v1_i] == op.value2[ps.v2_i]) {
  //       ps.v1_new_value += op.value1[ps.v1_i].replace(/</g, '<').replace('>', '>')
  //       ps.v2_new_value += op.value2[ps.v2_i].replace(/</g, '<').replace('>', '>')
  //       ps.v1_i += 1
  //       ps.v2_i += 1
  //       if (ps.v1_i >= op.value1.length) {
  //         ps.v2_new_value += "<span style='" + op.value2_style + "'>" + op.value2.substr(ps.v2_i).replace(/</g, '<').replace('>', '>') + '</span>'
  //         break
  //       }
  //       if (ps.v2_i >= op.value2.length) {
  //         ps.v1_new_value += "<span style='" + op.value1_style + "'>" + op.value1.substr(ps.v1_i).replace(/</g, '<').replace('>', '>') + '</span>'
  //         break
  //       }
  //     } else {
  //       ps.v1_index = ps.v1_i + 1
  //       ps.v1_eq_length = 0
  //       ps.v1_eq_max = 0
  //       ps.v1_start = ps.v1_i + 1
  //       while (ps.v1_index < op.value1.length) {
  //         if (op.value1[ps.v1_index] == op.value2[ps.v2_i + ps.v1_eq_length]) {
  //           ps.v1_eq_length += 1
  //         } else if (ps.v1_eq_length > 0) {
  //           if (ps.v1_eq_max < ps.v1_eq_length) {
  //             ps.v1_eq_max = ps.v1_eq_length
  //             ps.v1_start = ps.v1_index - ps.v1_eq_length
  //           }
  //           ps.v1_eq_length = 0
  //           break // 只寻找最近的
  //         }
  //         ps.v1_index += 1
  //       }
  //       if (ps.v1_eq_max < ps.v1_eq_length) {
  //         ps.v1_eq_max = ps.v1_eq_length
  //         ps.v1_start = ps.v1_index - ps.v1_eq_length
  //       }

  //       ps.v2_index = ps.v2_i + 1
  //       ps.v2_eq_length = 0
  //       ps.v2_eq_max = 0
  //       ps.v2_start = ps.v2_i + 1
  //       while (ps.v2_index < op.value2.length) {
  //         if (op.value2[ps.v2_index] == op.value1[ps.v1_i + ps.v2_eq_length]) {
  //           ps.v2_eq_length += 1
  //         } else if (ps.v2_eq_length > 0) {
  //           if (ps.v2_eq_max < ps.v2_eq_length) {
  //             ps.v2_eq_max = ps.v2_eq_length
  //             ps.v2_start = ps.v2_index - ps.v2_eq_length
  //           }
  //           ps.v1_eq_length = 0
  //           break // 只寻找最近的
  //         }
  //         ps.v2_index += 1
  //       }
  //       if (ps.v2_eq_max < ps.v2_eq_length) {
  //         ps.v2_eq_max = ps.v2_eq_length
  //         ps.v2_start = ps.v2_index - ps.v2_eq_length
  //       }
  //       if (ps.v1_eq_max < op.eq_min && ps.v1_start - ps.v1_i > op.eq_index) {
  //         ps.v1_eq_max = 0
  //       }
  //       if (ps.v2_eq_max < op.eq_min && ps.v2_start - ps.v2_i > op.eq_index) {
  //         ps.v2_eq_max = 0
  //       }
  //       if ((ps.v1_eq_max == 0 && ps.v2_eq_max == 0)) {
  //         ps.v1_new_value += "<span style='" + op.value1_style + "'>" + op.value1[ps.v1_i].replace(/</g, '<').replace('>', '>') + '</span>'
  //         ps.v2_new_value += "<span style='" + op.value2_style + "'>" + op.value2[ps.v2_i].replace(/</g, '<').replace('>', '>') + '</span>'
  //         ps.v1_i += 1
  //         ps.v2_i += 1

  //         if (ps.v1_i >= op.value1.length) {
  //           ps.v2_new_value += "<span style='" + op.value2_style + "'>" + op.value2.substr(ps.v2_i).replace(/</g, '<').replace('>', '>') + '</span>'
  //           break
  //         }
  //         if (ps.v2_i >= op.value2.length) {
  //           ps.v1_new_value += "<span style='" + op.value1_style + "'>" + op.value1.substr(ps.v1_i).replace(/</g, '<').replace('>', '>') + '</span>'
  //           break
  //         }
  //       } else if (ps.v1_eq_max > ps.v2_eq_max) {
  //         ps.v1_new_value += "<span style='" + op.value1_style + "'>" + op.value1.substr(ps.v1_i, ps.v1_start - ps.v1_i).replace(/</g, '<').replace('>', '>') + '</span>'
  //         ps.v1_i = ps.v1_start
  //       } else {
  //         ps.v2_new_value += "<span style='" + op.value2_style + "'>" + op.value2.substr(ps.v2_i, ps.v2_start - ps.v2_i).replace(/</g, '<').replace('>', '>') + '</span>'
  //         ps.v2_i = ps.v2_start
  //       }
  //     }
  //   }
  //   op.value1 = ps.v1_new_value
  //   op.value2 = ps.v2_new_value
  //   return op
}

/**
 * 【关闭tab】
 * 传递一个参数route，为tab站在所在的路由对象。
 *
 */
export function closeTab(route) {
  store.dispatch('delVisitedViews', route).then((views) => {
    const latestView = views.slice(-1)[0]
    if (latestView) {
      router.push(latestView)
    } else {
      router.push('/')
    }
  })
}

/**
 * 获取uuid
 */
export function getUUID() {
  return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {
    return (c === 'x' ? (Math.random() * 16 | 0) : ('r&0x3' | '0x8')).toString(16)
  })
}

/**
 * 封装查询条件
 * @param form
 */
export function buildQueryCondition(form) {
  let queryCondition = []
  for (let key in form) {
    // 不组装表单查询项的匹配模式
    if (key.includes('_criteria')) {
      continue
    }
    if (form[key] != null && form[key] !== undefined && form[key] !== '') {
      queryCondition.push({
        property: key,
        value: form[key],
        // EQ(=),NE(!=),GT(>),GE(>=),LT(<),LE(<=),LIKE,BETWEEN
        type: form[key + '_criteria'] || 'EQ'
      })
    }
  }
  // console.log('buildQueryCondition:', queryCondition)
  return queryCondition
}

/**
 * 对象属性对拷
 * @param target 目标对象
 * @param source 源对象
 * @param append true 将 source 对象中(多余的属性)拷贝至 target 对象
 */
export function copyProperties(target, source, append = false) {
  if (append) {
    for (let key in source) {
      target[key] = source[key]
    }
  } else {
    for (let key in target) {
      if (source[key] !== null && source[key] !== undefined) {
        target[key] = source[key]
      }
    }
  }
}

/**
 * 去重
 * @param arrs 对象数组
 * @param key 指定比对的字段，该字段的内容相同则视为重复数据
 */
export function repeat(arrs, key) {
  // console.log('repeat', arrs);
  let hash = {}
  return arrs.reduce(function (item, next) {
    if (!hash[next[key]]) {
      hash[next[key]] = true && item.push(next)
    }
    return item
  }, [])
}
